package com.guyu.plugin.satoken.listener;

import cn.dev33.satoken.listener.SaTokenListenerForLog;
import cn.dev33.satoken.stp.SaLoginModel;
import com.guyu.common.web.util.GyServletUtils;
import com.guyu.plugin.log.enums.BusinessStatus;
import com.guyu.plugin.log.enums.BusinessType;
import com.guyu.plugin.log.event.LoginLogEvent;
import org.dromara.hutool.extra.spring.SpringUtil;

/**
 * <p> 用户登录登出日志 </p>
 *
 * @author tanyunpeng
 * @date 2024/7/5
 */
public class GySaTokenListener extends SaTokenListenerForLog {

    /**
     * 每次登录时触发
     */
    @Override
    public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
        super.doLogin(loginType, loginId, tokenValue, loginModel);
        // 记录登录日志
        save(loginType, loginId, tokenValue, loginModel.getDevice(), BusinessType.LOGIN);
    }

    /**
     * 每次注销时触发
     */
    @Override
    public void doLogout(String loginType, Object loginId, String tokenValue) {
        super.doLogout(loginType, loginId, tokenValue);
        // 记录登出日志
        save(loginType, loginId, tokenValue, "", BusinessType.LOGOUT);
    }

    /**
     * 每次被踢下线时触发
     */
    @Override
    public void doKickout(String loginType, Object loginId, String tokenValue) {
        super.doKickout(loginType, loginId, tokenValue);
        // 记录登录日志
        save(loginType, loginId, tokenValue, "", BusinessType.KICK_OUT);
    }

    /**
     * 每次被顶下线时触发
     */
    @Override
    public void doReplaced(String loginType, Object loginId, String tokenValue) {
        super.doReplaced(loginType, loginId, tokenValue);
        // 记录登录日志
        save(loginType, loginId, tokenValue, "", BusinessType.REPLACED);
    }

    /**
     * 每次被封禁时触发
     */
    @Override
    public void doDisable(String loginType, Object loginId, String service, int level, long disableTime) {
        super.doDisable(loginType, loginId, service, level, disableTime);
        save(loginType, loginId, "", "", BusinessType.DISABLE);
    }

    /**
     * 每次被解封时触发
     */
    @Override
    public void doUntieDisable(String loginType, Object loginId, String service) {
        super.doUntieDisable(loginType, loginId, service);
        save(loginType, loginId, "", "", BusinessType.UNTIE_DISABLE);
    }

    /**
     * 每次打开二级认证时触发
     */
    @Override
    public void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) {
        super.doOpenSafe(loginType, tokenValue, service, safeTime);
    }

    /**
     * 每次创建Session时触发
     */
    @Override
    public void doCloseSafe(String loginType, String tokenValue, String service) {
        super.doCloseSafe(loginType, tokenValue, service);
    }

    /**
     * 每次创建Session时触发
     */
    @Override
    public void doCreateSession(String id) {
        super.doCreateSession(id);
    }

    /**
     * 每次注销Session时触发
     */
    @Override
    public void doLogoutSession(String id) {
        super.doLogoutSession(id);
    }

    /**
     * 每次Token续期时触发
     */
    @Override
    public void doRenewTimeout(String tokenValue, Object loginId, long timeout) {
        super.doRenewTimeout(tokenValue, loginId, timeout);
    }

    /**
     * 记录用户日志
     */
    private void save(String loginType, Object loginId, String tokenValue, String device, BusinessType businessType) {
        LoginLogEvent loginLog = new LoginLogEvent();
        loginLog.setLoginType(loginType);
        loginLog.setLoginId(loginId);
        loginLog.setClientType(device);
        loginLog.setTokenValue(tokenValue);
        loginLog.setType(businessType);
        loginLog.setStatus(BusinessStatus.SUCCESS);
        loginLog.setOperTime(System.currentTimeMillis());
        loginLog.setRequest(GyServletUtils.getRequest());
        SpringUtil.getApplicationContext().publishEvent(loginLog);
    }
}
